package com.teacher.game.framework.util;

import android.graphics.Bitmap;
import android.util.Log;
import android.util.LruCache;

import java.util.HashMap;
import java.util.Map;

/**
 * Bitmap缓存管理器 - 优化内存使用和加载性能
 * 使用LRU算法管理Bitmap缓存，避免重复加载和内存泄漏
 */
public class BitmapCache {
    
    private static final String TAG = "BitmapCache";
    private static BitmapCache instance;
    
    // LRU缓存，基于内存大小
    private final LruCache<String, Bitmap> memoryCache;
    
    // 引用计数，跟踪Bitmap使用情况
    private final Map<String, Integer> referenceCount;
    
    // 缓存统计
    private int cacheHits = 0;
    private int cacheMisses = 0;
    
    /**
     * 私有构造函数
     */
    private BitmapCache() {
        // 获取系统可用内存
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        
        // 使用1/8的可用内存作为缓存空间
        final int cacheSize = maxMemory / 8;
        
        Log.d(TAG, "初始化Bitmap缓存，大小: " + cacheSize + "KB");
        
        memoryCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                // 返回Bitmap占用的内存大小（KB）
                return bitmap.getByteCount() / 1024;
            }
            
            @Override
            protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {
                if (evicted) {
                    Log.d(TAG, "Bitmap被LRU算法移除: " + key);
                    // 检查是否还有引用，没有则回收
                    Integer refCount = referenceCount.get(key);
                    if (refCount == null || refCount <= 0) {
                        if (!oldValue.isRecycled()) {
                            oldValue.recycle();
                        }
                        referenceCount.remove(key);
                    }
                }
            }
        };
        
        referenceCount = new HashMap<>();
    }
    
    /**
     * 获取单例实例
     * @return BitmapCache实例
     */
    public static synchronized BitmapCache getInstance() {
        if (instance == null) {
            instance = new BitmapCache();
        }
        return instance;
    }
    
    /**
     * 获取Bitmap
     * @param key 缓存键
     * @return Bitmap对象，如果不存在返回null
     */
    public Bitmap getBitmap(String key) {
        Bitmap bitmap = memoryCache.get(key);
        if (bitmap != null && !bitmap.isRecycled()) {
            cacheHits++;
            // 增加引用计数
            incrementReference(key);
            Log.d(TAG, "缓存命中: " + key);
            return bitmap;
        } else {
            cacheMisses++;
            if (bitmap != null && bitmap.isRecycled()) {
                // 移除已回收的Bitmap
                memoryCache.remove(key);
                referenceCount.remove(key);
                Log.w(TAG, "发现已回收的Bitmap，已移除: " + key);
            }
            Log.d(TAG, "缓存未命中: " + key);
            return null;
        }
    }
    
    /**
     * 缓存Bitmap
     * @param key 缓存键
     * @param bitmap Bitmap对象
     */
    public void putBitmap(String key, Bitmap bitmap) {
        if (key != null && bitmap != null && !bitmap.isRecycled()) {
            memoryCache.put(key, bitmap);
            incrementReference(key);
            Log.d(TAG, "Bitmap已缓存: " + key + ", 大小: " + (bitmap.getByteCount() / 1024) + "KB");
        }
    }
    
    /**
     * 释放Bitmap引用
     * @param key 缓存键
     */
    public void releaseBitmap(String key) {
        if (key != null) {
            Integer refCount = referenceCount.get(key);
            if (refCount != null && refCount > 0) {
                refCount--;
                referenceCount.put(key, refCount);
                Log.d(TAG, "Bitmap引用减少: " + key + ", 当前引用数: " + refCount);
                
                // 如果没有引用了，可以考虑从缓存中移除（让LRU算法决定）
                if (refCount <= 0) {
                    Log.d(TAG, "Bitmap无引用: " + key);
                }
            }
        }
    }
    
    /**
     * 增加引用计数
     * @param key 缓存键
     */
    private void incrementReference(String key) {
        Integer refCount = referenceCount.get(key);
        if (refCount == null) {
            refCount = 0;
        }
        refCount++;
        referenceCount.put(key, refCount);
    }
    
    /**
     * 清空所有缓存
     */
    public void clearCache() {
        Log.d(TAG, "清空Bitmap缓存");
        
        // 回收所有Bitmap
        memoryCache.evictAll();
        referenceCount.clear();
        
        // 重置统计
        cacheHits = 0;
        cacheMisses = 0;
    }
    
    /**
     * 获取缓存统计信息
     * @return 缓存统计字符串
     */
    public String getCacheStats() {
        int hitRate = 0;
        int total = cacheHits + cacheMisses;
        if (total > 0) {
            hitRate = (cacheHits * 100) / total;
        }
        
        return String.format("缓存统计 - 命中: %d, 未命中: %d, 命中率: %d%%, 当前大小: %d/%d KB",
            cacheHits, cacheMisses, hitRate, memoryCache.size(), memoryCache.maxSize());
    }
    
    /**
     * 获取缓存命中率
     * @return 命中率（0-100）
     */
    public int getCacheHitRate() {
        int total = cacheHits + cacheMisses;
        return total > 0 ? (cacheHits * 100) / total : 0;
    }
    
    /**
     * 检查Bitmap是否在缓存中
     * @param key 缓存键
     * @return 是否存在
     */
    public boolean contains(String key) {
        return memoryCache.get(key) != null;
    }
    
    /**
     * 获取当前缓存使用量（KB）
     * @return 缓存使用量
     */
    public int getCacheSize() {
        return memoryCache.size();
    }
    
    /**
     * 获取最大缓存容量（KB）
     * @return 最大缓存容量
     */
    public int getMaxCacheSize() {
        return memoryCache.maxSize();
    }
}